package com.appspot.bibtable.view.html;

import java.io.IOException;
import java.io.Writer;
import java.util.HashSet;
import java.util.Set;

import javax.jdo.PersistenceManager;

import com.appspot.bibtable.model.ReferenceEntity;
import com.appspot.bibtable.util.StringUtility;
import com.appspot.bibtable.view.Table;
import com.appspot.bibtable.view.TableCellType;

public abstract class HtmlTable extends Table
{
	protected static final String newline = System.getProperty("line.separator");
	private static final int NULL_INDEX = -1;

	private String id;
	private Set<String> classes;
	private String caption;
	private PersistenceManager manager;

	private int row;
	private int column;

	public HtmlTable()
	{
		classes = new HashSet<String>();
	}

	public int getRow()
	{
		return row;
	}

	public int getColumn()
	{
		return column;
	}

	public String getId()
	{
		return id;
	}

	public void setId(String id)
	{
		this.id = id;
	}

	public String getClassAttribute()
	{
		if (classes.size() == 0)
		{
			return null;
		}
		StringBuilder builder = new StringBuilder();
		for (String c : classes)
		{
			builder.append(c);
			builder.append(' ');
		}
		builder.deleteCharAt(builder.length() - 1);
		return builder.toString();
	}

	public void addClass(String c)
	{
		if (StringUtility.isNullOrEmpty(c))
		{
			throw new IllegalArgumentException();
		}
		classes.add(c);
	}

	public void removeClass(String c)
	{
		classes.remove(c);
	}

	public String getCaption()
	{
		return caption;
	}

	public void setCaption(String caption)
	{
		this.caption = caption;
	}

	@Override
	public void endTable(Writer writer) throws IOException
	{
		writer.write("</table>");
	}

	@Override
	public void startTable(Writer writer) throws IOException
	{
		writer.write("<table");
		String id = getId();
		if (id != null)
		{
			writer.write(" id=\"" + id + "\"");
		}
		String c = getClassAttribute();
		if (c != null)
		{
			writer.write(" class=\"" + c + "\"");
		}
		writer.write(">");
		String caption = getCaption();
		if (caption != null)
		{
			writer.write("<caption>" + caption + "</caption>");
		}
	}

	public void endRow(Writer writer) throws IOException
	{
		endRow(writer, NULL_INDEX);
	}

	@Override
	public void endRow(Writer writer, int row) throws IOException
	{
		row = getRow();
		writer.write("</tr>");
		this.row = row + 1;
		this.column = 0;
	}

	public void startRow(Writer writer) throws IOException
	{
		startRow(writer, NULL_INDEX);
	}

	@Override
	public void startRow(Writer writer, int row) throws IOException
	{
		row = getRow();
		writer.write("<tr>");
	}
	
	public void endCell(Writer writer, TableCellType type) throws IOException
	{
		endCell(writer, NULL_INDEX, NULL_INDEX, type);
	}

	@Override
	public void endCell(Writer writer, int row, int column, TableCellType type) throws IOException
	{
		row = getRow();
		column = getColumn();
		switch (type)
		{
			case HEADING:
				writer.write("</th>");
				break;
			default:
				writer.write("</td>");
				break;
		}
		this.column++;
	}
	
	public void startCell(Writer writer, TableCellType type) throws IOException
	{
		startCell(writer, NULL_INDEX, NULL_INDEX, type);
	}

	@Override
	public void startCell(Writer writer, int row, int column, TableCellType type) throws IOException
	{
		row = getRow();
		column = getColumn();
		switch (type)
		{
			case HEADING:
				writer.write("<th>");
				break;
			default:
				writer.write("<td>");
				break;
		}
	}

	public abstract void addReference(ReferenceEntity entity, Writer writer) throws IOException;

	public PersistenceManager getPersistenceManager()
	{
		return manager;
	}

	public void setPersistenceManager(PersistenceManager manager)
	{
		this.manager = manager;
	}
}
